mod config;
mod controllers;
mod error;
mod middleware;
mod models;
mod services;
mod utils;

use std::sync::Arc;

use axum::{
    http::{HeaderValue, Method},
    Extension,
};
use config::{Config, DBClient};
use controllers::create_router;
use dotenvy::dotenv;
use tower_http::cors;

#[tokio::main]
async fn main() {
    dotenv().ok();

    let config = Config::init();

    let db_client = DBClient::init(&config).await;

    let listener = tokio::net::TcpListener::bind("0.0.0.0:8000").await.unwrap();

    println!("{}", format!("Server is running on http://localhost:8000"));

    let app_state = Arc::new(AppState { config, db_client });

    let cors = cors::CorsLayer::new()
        .allow_headers(tower_http::cors::Any)
        .allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE])
        .allow_origin("http://localhost:5173".parse::<HeaderValue>().unwrap());

    let app = create_router().layer(Extension(app_state)).layer(cors);

    axum::serve(listener, app).await.unwrap();
}

#[derive(Debug)]
pub struct AppState {
    pub config: Config,
    pub db_client: DBClient,
}
